home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / io / PushbackReader.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  6.9 KB  |  238 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)PushbackReader.java    1.12 98/07/07
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.io;
  16.  
  17.  
  18. /**
  19.  * A character-stream reader that allows characters to be pushed back into the
  20.  * stream.
  21.  *
  22.  * @version     1.12, 98/07/07
  23.  * @author    Mark Reinhold
  24.  * @since    JDK1.1
  25.  */
  26.  
  27. public class PushbackReader extends FilterReader {
  28.  
  29.     /** Pushback buffer */
  30.     private char[] buf;
  31.  
  32.     /** Current position in buffer */
  33.     private int pos;
  34.  
  35.     /**
  36.      * Create a new pushback reader with a pushback buffer of the given size.
  37.      *
  38.      * @param   in   The reader from which characters will be read
  39.      * @param    size The size of the pushback buffer
  40.      * @exception IllegalArgumentException if size is <= 0
  41.      */
  42.     public PushbackReader(Reader in, int size) {
  43.     super(in);
  44.         if (size <= 0) {
  45.             throw new IllegalArgumentException("size <= 0");
  46.         }
  47.     this.buf = new char[size];
  48.     this.pos = size;
  49.     }
  50.  
  51.     /**
  52.      * Create a new pushback reader with a one-character pushback buffer.
  53.      *
  54.      * @param   in  The reader from which characters will be read
  55.      */
  56.     public PushbackReader(Reader in) {
  57.     this(in, 1);
  58.     }
  59.  
  60.     /** Check to make sure that the stream has not been closed. */
  61.     private void ensureOpen() throws IOException {
  62.     if (buf == null)
  63.         throw new IOException("Stream closed");
  64.     }
  65.  
  66.     /**
  67.      * Read a single character.
  68.      *
  69.      * @return     The character read, or -1 if the end of the stream has been
  70.      *             reached
  71.      *
  72.      * @exception  IOException  If an I/O error occurs
  73.      */
  74.     public int read() throws IOException {
  75.     synchronized (lock) {
  76.         ensureOpen();
  77.         if (pos < buf.length)
  78.         return buf[pos++];
  79.         else
  80.         return super.read();
  81.     }
  82.     }
  83.  
  84.     /**
  85.      * Read characters into a portion of an array.
  86.      *
  87.      * @param      cbuf  Destination buffer
  88.      * @param      off   Offset at which to start writing characters
  89.      * @param      len   Maximum number of characters to read
  90.      *
  91.      * @return     The number of characters read, or -1 if the end of the
  92.      *             stream has been reached
  93.      *
  94.      * @exception  IOException  If an I/O error occurs
  95.      */
  96.     public int read(char cbuf[], int off, int len) throws IOException {
  97.     synchronized (lock) {
  98.         ensureOpen();
  99.             try {
  100.                 if (len <= 0) {
  101.                     if (len < 0) {
  102.                         throw new IndexOutOfBoundsException();
  103.                     } else if ((off < 0) || (off > cbuf.length)) {
  104.                         throw new IndexOutOfBoundsException();
  105.                     }
  106.                     return 0;
  107.                 }
  108.                 int avail = buf.length - pos;
  109.                 if (avail > 0) {
  110.                     if (len < avail)
  111.                         avail = len;
  112.                     System.arraycopy(buf, pos, cbuf, off, avail);
  113.                     pos += avail;
  114.                     off += avail;
  115.                     len -= avail;
  116.                 }
  117.                 if (len > 0) {
  118.                     len = super.read(cbuf, off, len);
  119.                     if (len == -1) {
  120.                         return (avail == 0) ? -1 : avail;
  121.                     }
  122.                     return avail + len;
  123.                 }
  124.                 return avail;
  125.             } catch (ArrayIndexOutOfBoundsException e) {
  126.                 throw new IndexOutOfBoundsException();
  127.             }
  128.         }
  129.     }
  130.  
  131.     /**
  132.      * Push back a single character.
  133.      *
  134.      * @param  c  The character to push back
  135.      *
  136.      * @exception  IOException  If the pushback buffer is full,
  137.      *                          or if some other I/O error occurs
  138.      */
  139.     public void unread(int c) throws IOException {
  140.     synchronized (lock) {
  141.         ensureOpen();
  142.         if (pos == 0)
  143.         throw new IOException("Pushback buffer overflow");
  144.         buf[--pos] = (char) c;
  145.     }
  146.     }
  147.  
  148.     /**
  149.      * Push back a portion of an array of characters by copying it to the
  150.      * front of the pushback buffer.  After this method returns, the next
  151.      * character to be read will have the value <code>cbuf[off]</code>, the
  152.      * character after that will have the value <code>cbuf[off+1]</code>, and
  153.      * so forth.
  154.      *
  155.      * @param  cbuf  Character array
  156.      * @param  off   Offset of first character to push back
  157.      * @param  len   Number of characters to push back
  158.      *
  159.      * @exception  IOException  If there is insufficient room in the pushback
  160.      *                          buffer, or if some other I/O error occurs
  161.      */
  162.     public void unread(char cbuf[], int off, int len) throws IOException {
  163.     synchronized (lock) {
  164.         ensureOpen();
  165.         if (len > pos)
  166.         throw new IOException("Pushback buffer overflow");
  167.         pos -= len;
  168.         System.arraycopy(cbuf, off, buf, pos, len);
  169.     }
  170.     }
  171.  
  172.     /**
  173.      * Push back an array of characters by copying it to the front of the
  174.      * pushback buffer.  After this method returns, the next character to be
  175.      * read will have the value <code>cbuf[0]</code>, the character after that
  176.      * will have the value <code>cbuf[1]</code>, and so forth.
  177.      *
  178.      * @param  cbuf  Character array to push back
  179.      *
  180.      * @exception  IOException  If there is insufficient room in the pushback
  181.      *                          buffer, or if some other I/O error occurs
  182.      */
  183.     public void unread(char cbuf[]) throws IOException {
  184.     unread(cbuf, 0, cbuf.length);
  185.     }
  186.  
  187.     /**
  188.      * Tell whether this stream is ready to be read.
  189.      *
  190.      * @exception  IOException  If an I/O error occurs
  191.      */
  192.     public boolean ready() throws IOException {
  193.     synchronized (lock) {
  194.         ensureOpen();
  195.         return (pos < buf.length) || super.ready();
  196.     }
  197.     }
  198.  
  199.     /**
  200.      * Mark the present position in the stream. The <code>mark</code>
  201.      * for class <code>PushbackReader</code> always throws an exception.
  202.      *
  203.      * @exception  IOException  Always, since mark is not supported
  204.      */
  205.     public void mark(int readAheadLimit) throws IOException {
  206.     throw new IOException("mark/reset not supported");
  207.     }
  208.  
  209.     /**
  210.      * Reset the stream. The <code>reset</code> method of 
  211.      * <code>PushbackReader</code> always throws an exception.
  212.      *
  213.      * @exception  IOException  Always, since reset is not supported
  214.      */
  215.     public void reset() throws IOException {
  216.     throw new IOException("mark/reset not supported");
  217.     }
  218.  
  219.     /**
  220.      * Tell whether this stream supports the mark() operation, which it does
  221.      * not.
  222.      */
  223.     public boolean markSupported() {
  224.     return false;
  225.     }
  226.  
  227.     /**
  228.      * Close the stream.
  229.      *
  230.      * @exception  IOException  If an I/O error occurs
  231.      */
  232.     public void close() throws IOException {
  233.     super.close();
  234.     buf = null;
  235.     }
  236.  
  237. }
  238.